namespace ESupervision.Migrations
{
    using System;
    using System.Collections.Generic;
    using System.Data.Entity;
    using System.Data.Entity.Migrations;
    using System.Linq;
    using Microsoft.AspNet.Identity;
    using Microsoft.AspNet.Identity.EntityFramework;
    using System.Data.Entity.Validation;

    using ESupervision.Models;

    internal sealed class Configuration : DbMigrationsConfiguration<ESupervision.Models.ApplicationDbContext>
    {
        public Configuration()
        {
            AutomaticMigrationsEnabled = true;
            AutomaticMigrationDataLossAllowed = true;
        }

        protected override void Seed(ESupervision.Models.ApplicationDbContext context)
        {
            //  This method will be called after migrating to the latest version.

            //  You can use the DbSet<T>.AddOrUpdate() helper extension method 
            //  to avoid creating duplicate seed data. E.g.
            //
            //    context.People.AddOrUpdate(
            //      p => p.FullName,
            //      new Person { FullName = "Andrew Peters" },
            //      new Person { FullName = "Brice Lambson" },
            //      new Person { FullName = "Rowan Miller" }
            //    );
            //

            InitializeMembership(context);
            InitializeSampleMessage(context);

        }

        private void InitializeSampleMessage(ApplicationDbContext context)
        {

            if (context.Messages.Any(u => u.Subject == "Testing Message 1"))
            {
                return;
            }
            // Each Student sent 15 messages to Supervisor and SecondMarker

            var students = context.Students.ToList();
            if (students != null)
            {
                foreach (var student in students)
                {
                    List<ApplicationUser> receivers = new List<ApplicationUser>
                {
                    student.Supervisor,
                    student.SecondMarker
                };
                    for (int i = 0; i < 15; i++)
                    {
                        // Create Message
                        Message message = new Message
                        {
                            Sender = student,
                            SentTime = DateTime.Now,
                            Subject = "Testing Message " + i,
                            Body = "Testing Message Body " + i
                        };
                        SendMessage(context, message, receivers);
                    }
                }
            }

            var staffs = context.Teachers.ToList();
            if(staffs != null)
            {
                foreach (var staff in context.Teachers)
                {
                    if (staff.SupervisedStudents != null)
                    {
                        var superVisedStudent = staff.SupervisedStudents.ToList();
                        if (superVisedStudent != null)
                        {
                            foreach (var student in staff.SupervisedStudents)
                            {
                                List<ApplicationUser> receivers = new List<ApplicationUser>
                                    {
                                        student,
                                        student.SecondMarker
                                    };

                                for (int i = 0; i < 7; i++)
                                {
                                    // Create Message
                                    Message message = new Message
                                    {
                                        Sender = staff,
                                        SentTime = DateTime.Now,
                                        Subject = "Testing Message Supervisor " + i,
                                        Body = "Testing Message Supervisor Body " + i
                                    };
                                    SendMessage(context, message, receivers);
                                }
                            }
                        }
                    }


                    if (staff.SecondMarkedStudents != null)
                    {
                        var secondMarkedStudents = staff.SecondMarkedStudents.ToList();
                        if (secondMarkedStudents != null)
                        {
                            foreach (var student in staff.SecondMarkedStudents)
                            {
                                List<ApplicationUser> receivers = new List<ApplicationUser>
                                    {
                                        student,
                                        student.Supervisor
                                    };

                                for (int i = 0; i < 7; i++)
                                {
                                    // Create Message
                                    Message message = new Message
                                    {
                                        Sender = staff,
                                        SentTime = DateTime.Now,
                                        Subject = "Testing Message Second Marker " + i,
                                        Body = "Testing Message Second Marker " + i
                                    };
                                    SendMessage(context, message, receivers);
                                }
                            }
                        }
                    }
                }

            }

        }


        private void SendMessage(ApplicationDbContext context, Message message, List<ApplicationUser> receivers){


            context.Messages.Add(message);
            context.SaveChanges();
            // Create MesageRecipients
            foreach (ApplicationUser receiver in receivers)
            {
                MessageRecipient messageRecipient = new MessageRecipient { Message = message, ReceiverUserID = receiver.Id,
                                                                        MessageStatus = MessageStatus.Unread, ReceivedTime = message.SentTime};
                context.MessageRecipients.Add(messageRecipient);
            }

            MessageSent messageSent = new MessageSent
            {
                Message = message,
                SentUserID = message.SentByUserId,
                MessageStatus = MessageStatus.Read,
                SentTime = message.SentTime
            };


            context.MessageSents.Add(messageSent);



            context.SaveChanges();
            
        }
        private void InitializeMembership(ESupervision.Models.ApplicationDbContext context)
        {

            try
            {
                // Create some roles
                // Student, Staff, Authorised


                if(!context.Roles.Any(u => u.Name == "Student"))
                {
                    context.Roles.Add(new IdentityRole { Name = "Student" });
                }

                if (!context.Roles.Any(u => u.Name == "Teacher"))
                {
                    context.Roles.Add(new IdentityRole { Name = "Teacher" });
                }

                if (!context.Roles.Any(u => u.Name == "Authorised"))
                {
                    context.Roles.Add(new IdentityRole { Name = "Authorised" });
                }
                
                context.SaveChanges();


                // Create some sample student

                var userStore = new UserStore<ApplicationUser>(context);
                var userManager = new UserManager<ApplicationUser>(userStore);

                // We assume that the user "alibaba" always exists in my database if it initialized
                /*if (!context.Users.Any(u => u.UserName == "alibaba"))
                {
                    var user = new ApplicationUser { UserName = "alibaba" };
                    userManager.Create(user, "@libaba");
                    userManager.AddToRole(user.Id, "Student");
                }*/



                var passwordHash = new PasswordHasher();
                string password = passwordHash.HashPassword("123456");
                //Create authorised staff sample data
                var authorisedStaffs = new List<AuthorisedStaff>
            {
                new AuthorisedStaff{UserName = "sang.le", FirstName = "Sang", LastName = "Le", Email = "Anhntlgc60303@fpt.edu.vn",
                                    Address = "33 Truong Cong Dinh", JoinDate = DateTime.Parse("2010-02-18"), 
                                    Phone = "0903666892", Birthday = DateTime.Parse("1970-02-18"), PasswordHash = password},
                new AuthorisedStaff{UserName = "nghia.tran", FirstName = "Nghia", LastName = "Tran", Email = "hieptptgt60677@fpt.edu.vn",
                                    Address = "33 Truong Cong Dinh", JoinDate = DateTime.Parse("2010-02-18"), 
                                    Phone = "0903666892", Birthday = DateTime.Parse("1982-03-27"), PasswordHash = password}
            };

                foreach (var authorisedStaff in authorisedStaffs)
                {
                    if (!context.Users.Any(u => u.UserName == authorisedStaff.UserName))
                    {
                        /*var result = userManager.Create(authorisedStaff, "123456");

                        if (result.Succeeded)
                        {
                            var user = userManager.FindByName(authorisedStaff.UserName);
                            userManager.AddToRole(user.Id, "Authorised");
                        }*/

                        context.AuthorisedStaffs.AddOrUpdate(authorisedStaff);
                        context.SaveChanges();
                        userManager.AddToRole(authorisedStaff.Id, "Authorised");

                    }
                }

                // Create staff sample data

                var staffs = new List<Teacher>
            {
                new Teacher{UserName = "bao.teacher", FirstName = "Bao", LastName = "Tran", Email = "Anhntlgc60303@fpt.edu.vn",
                                    Address = "33 Truong Cong Dinh", HireDate = DateTime.Parse("2010-02-18"), 
                                    Phone = "0903666892", Birthday = DateTime.Parse("1970-02-18"), PasswordHash = password},
                new Teacher{UserName = "long.teacher", FirstName = "Long", LastName = "Nguyen", Email = "hieptptgt60677@fpt.edu.vn",
                                    Address = "33 Truong Cong Dinh", HireDate = DateTime.Parse("2010-02-18"), 
                                    Phone = "0903666892", Birthday = DateTime.Parse("1982-03-27"), PasswordHash = password},
                new Teacher{UserName = "tinh.teacher", FirstName = "Tinh", LastName = "Chau", Email = "Anhntlgc60303@fpt.edu.vn",
                                    Address = "33 Truong Cong Dinh", HireDate = DateTime.Parse("2010-02-18"), 
                                    Phone = "0903666892", Birthday = DateTime.Parse("1970-02-18"), PasswordHash = password},
                new Teacher{UserName = "tri.teacher", FirstName = "Tri", LastName = "Ngo", Email = "hieptptgt60677@fpt.edu.vn",
                                    Address = "33 Truong Cong Dinh", HireDate = DateTime.Parse("2010-02-18"), 
                                    Phone = "0903666892", Birthday = DateTime.Parse("1982-03-27"), PasswordHash = password},
                new Teacher{UserName = "tu.teacher", FirstName = "Tu", LastName = "Duong", Email = "Anhntlgc60303@fpt.edu.vn",
                                    Address = "33 Truong Cong Dinh", HireDate = DateTime.Parse("2010-02-18"), 
                                    Phone = "0903666892", Birthday = DateTime.Parse("1970-02-18"), PasswordHash = password},
                new Teacher{UserName = "sinh.teacher", FirstName = "Sinh", LastName = "Nguyen", Email = "hieptptgt60677@fpt.edu.vn",
                                    Address = "33 Truong Cong Dinh", HireDate = DateTime.Parse("2010-02-18"), 
                                    Phone = "0903666892", Birthday = DateTime.Parse("1982-03-27"), PasswordHash = password},
                new Teacher{UserName = "tuan.teacher", FirstName = "Tuan", LastName = "Tran", Email = "Anhntlgc60303@fpt.edu.vn",
                                    Address = "33 Truong Cong Dinh", HireDate = DateTime.Parse("2010-02-18"), 
                                    Phone = "0903666892", Birthday = DateTime.Parse("1970-02-18"), PasswordHash = password},
                new Teacher{UserName = "thanh.teacher", FirstName = "Thanh", LastName = "Duong", Email = "hieptptgt60677@fpt.edu.vn",
                                    Address = "33 Truong Cong Dinh", HireDate = DateTime.Parse("2010-02-18"), 
                                    Phone = "0903666892", Birthday = DateTime.Parse("1982-03-27"), PasswordHash = password}
            };

                foreach (var staff in staffs)
                {
                    if (!context.Users.Any(u => u.UserName == staff.UserName))
                    {
                        /*var result = userManager.Create(authorisedStaff, "123456");

                        if (result.Succeeded)
                        {
                            var user = userManager.FindByName(authorisedStaff.UserName);
                            userManager.AddToRole(user.Id, "Authorised");
                        }*/

                        context.Teachers.AddOrUpdate(staff);
                        context.SaveChanges();
                        userManager.AddToRole(staff.Id, "Teacher");

                    }
                }

                // Create Student sample data
                var students = new List<Student>
                 {
                     new Student{UserName = "hiep.tang", FirstName = "Hiep", LastName = "Tang", Email = "tpthiep@gmail.com",
                                         Address = "33 Truong Cong Dinh", EnrollmentDate = DateTime.Parse("2015-01-15"), 
                                         Phone = "0903666892", Birthday = DateTime.Parse("1980-03-21"), PasswordHash = password,
                                         Supervisor = staffs[5], SecondMarker = staffs[1], AuthorisedStaff = authorisedStaffs[1]},
                     new Student{UserName = "tung.vu", FirstName = "Tung", LastName = "Vu", Email = "thanhtungteen@gmail.com",
                                         Address = "33 Truong Cong Dinh", EnrollmentDate = DateTime.Parse("2014-07-15"), 
                                         Phone = "0903666892", Birthday = DateTime.Parse("1992-04-10"),PasswordHash = password,
                                         Supervisor = staffs[5], SecondMarker = staffs[2], AuthorisedStaff = authorisedStaffs[1]},
                     new Student{UserName = "anh.lan", FirstName = "Anh", LastName = "Lan", Email = "nguyenthailananh@gmail.com",
                                         Address = "33 Truong Cong Dinh", EnrollmentDate = DateTime.Parse("2015-01-15"), 
                                         Phone = "0903666892", Birthday = DateTime.Parse("1993-03-10"),PasswordHash = password,
                                         Supervisor = staffs[1], SecondMarker = staffs[3], AuthorisedStaff = authorisedStaffs[1]},
                     new Student{UserName = "daniel.dang", FirstName = "Daniel", LastName = "Dang", Email = "danieldang28@gmail.com",
                                         Address = "33 Truong Cong Dinh", EnrollmentDate = DateTime.Parse("2015-01-15"), 
                                         Phone = "0903666892", Birthday = DateTime.Parse("1989-11-21"),PasswordHash = password,
                                         Supervisor = staffs[0], SecondMarker = staffs[1], AuthorisedStaff = authorisedStaffs[1]},
                     new Student{UserName = "thuong.student", FirstName = "Thuong", LastName = "Student", Email = "thuongstudent@gmail.com",
                                         Address = "33 Truong Cong Dinh", EnrollmentDate = DateTime.Parse("2014-07-15"), 
                                         Phone = "0903666892", Birthday = DateTime.Parse("1992-04-10"),PasswordHash = password,
                                         Supervisor = staffs[2], SecondMarker = staffs[5], AuthorisedStaff = authorisedStaffs[1]},
                     new Student{UserName = "giang.student", FirstName = "Giang", LastName = "Student", Email = "giangstudent@gmail.com",
                                         Address = "33 Truong Cong Dinh", EnrollmentDate = DateTime.Parse("2015-01-15"), 
                                         Phone = "0903666892", Birthday = DateTime.Parse("1993-03-10"),PasswordHash = password,
                                         Supervisor = staffs[4], SecondMarker = staffs[6], AuthorisedStaff = authorisedStaffs[1]},
                    new Student{UserName = "oanh.student", FirstName = "Oanh", LastName = "Student", Email = "oanhstudent@gmail.com",
                                         Address = "33 Truong Cong Dinh", EnrollmentDate = DateTime.Parse("2015-01-15"), 
                                         Phone = "0903666892", Birthday = DateTime.Parse("1980-03-21"),PasswordHash = password,
                                         Supervisor = staffs[6], SecondMarker = staffs[7], AuthorisedStaff = authorisedStaffs[0]},
                     new Student{UserName = "thong.student", FirstName = "Thong", LastName = "Student", Email = "thongstudent@gmail.com",
                                         Address = "33 Truong Cong Dinh", EnrollmentDate = DateTime.Parse("2014-07-15"), 
                                         Phone = "0903666892", Birthday = DateTime.Parse("1992-04-10"),PasswordHash = password,
                                         Supervisor = staffs[7], SecondMarker = staffs[4], AuthorisedStaff = authorisedStaffs[0]},
                     new Student{UserName = "linh.nguyen", FirstName = "Linh", LastName = "Nguyen", Email = "linhnguyen@gmail.com",
                                         Address = "33 Truong Cong Dinh", EnrollmentDate = DateTime.Parse("2015-01-15"), 
                                         Phone = "0903666892", Birthday = DateTime.Parse("1993-03-10"),PasswordHash = password,
                                         Supervisor = staffs[1], SecondMarker = staffs[2], AuthorisedStaff = authorisedStaffs[0]},
                     new Student{UserName = "phuc.student", FirstName = "Phuc", LastName = "Student", Email = "phucstudent@gmail.com",
                                         Address = "33 Truong Cong Dinh", EnrollmentDate = DateTime.Parse("2015-01-15"), 
                                         Phone = "0903666892", Birthday = DateTime.Parse("1989-11-21"),PasswordHash = password,
                                         Supervisor = staffs[4], SecondMarker = staffs[3], AuthorisedStaff = authorisedStaffs[0]},
                     new Student{UserName = "ngoc.student", FirstName = "Ngoc", LastName = "Student", Email = "ngocstudent@gmail.com",
                                         Address = "33 Truong Cong Dinh", EnrollmentDate = DateTime.Parse("2014-07-15"), 
                                         Phone = "0903666892", Birthday = DateTime.Parse("1992-04-10"),PasswordHash = password,
                                         Supervisor = staffs[6], SecondMarker = staffs[4], AuthorisedStaff = authorisedStaffs[0]},
                     new Student{UserName = "tuyen.student", FirstName = "Tuyen", LastName = "Student", Email = "tuyenstudent@gmail.com",
                                         Address = "33 Truong Cong Dinh", EnrollmentDate = DateTime.Parse("2015-01-15"), 
                                         Phone = "0903666892", Birthday = DateTime.Parse("1993-03-10"),PasswordHash = password,
                                         Supervisor = staffs[3], SecondMarker = staffs[6], AuthorisedStaff = authorisedStaffs[0]}
                 };


                 foreach (var student in students)
                 {
                     if (!context.Users.Any(u => u.UserName == student.UserName))
                     {
                         /*var result = userManager.Create(authorisedStaff, "123456");

                         if (result.Succeeded)
                         {
                             var user = userManager.FindByName(authorisedStaff.UserName);
                             userManager.AddToRole(user.Id, "Authorised");
                         }*/

                         context.Students.AddOrUpdate(student);
                         context.SaveChanges();
                         userManager.AddToRole(student.Id, "Student");

                     }
                 }

                 context.SaveChanges();

            }
            catch (System.Data.Entity.Validation.DbEntityValidationException e)
            {
                var outputLines = new List<string>();
                foreach (var eve in e.EntityValidationErrors)
                {
                    outputLines.Add(string.Format(
                        "{0}: Entity of type \"{1}\" in state \"{2}\" has the following validation errors:",
                        DateTime.Now, eve.Entry.Entity.GetType().Name, eve.Entry.State));
                    foreach (var ve in eve.ValidationErrors)
                    {
                        outputLines.Add(string.Format(
                            "- Property: \"{0}\", Error: \"{1}\"",
                            ve.PropertyName, ve.ErrorMessage));
                    }
                }
                //Write to file
                System.IO.File.AppendAllLines(@"c:\temp\errors.txt", outputLines);
                throw;

                // Showing it on screen
                throw new Exception(string.Join(",", outputLines.ToArray()));

            }
           
            
        }
    }
}
